home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1983 The Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #ifndef lint
- static char sccsid[] = "@(#)cmds.c 5.8 (Berkeley) 9/2/88";
- #endif /* not lint */
-
- #include "tip.h"
- /*
- * tip
- *
- * miscellaneous commands
- */
-
- int quant[] = { 60, 60, 24 };
-
- char null = '\0';
- char *sep[] = { "second", "minute", "hour" };
- static char *argv[10]; /* argument vector for take and put */
-
- sigfunc_t timeout(); /* timeout function called on alarm */
- sigfunc_t stopsnd(); /* SIGINT handler during file transfers */
- sigfunc_t intprompt(); /* used in handling SIG_INT during prompt */
- sigfunc_t intcopy(); /* interrupt routine for file transfers */
-
- /*
- * FTP - remote ==> local
- * get a file from the remote host
- */
- getfl(c)
- char c;
- {
- char buf[256], *cp, *expand();
-
- putchar(c);
- /*
- * get the UNIX receiving file's name
- */
- if (prompt("Local file name? ", copyname))
- return;
- cp = expand(copyname);
- if ((sfd = creat(cp, 0666)) < 0) {
- printf("\r\n%s: cannot creat\r\n", copyname);
- return;
- }
-
- /*
- * collect parameters
- */
- if (prompt("List command for remote system? ", buf)) {
- unlink(copyname);
- return;
- }
- transfer(buf, sfd, value(EOFREAD));
- }
-
- /*
- * Cu-like take command
- */
- /*ARGUSED*/
- cu_take(cc)
- char cc;
- {
- int fd, argc;
- char line[BUFSIZ], *expand(), *cp;
-
- if (prompt("[take] ", copyname))
- return;
- if ((argc = args(copyname, argv)) < 1 || argc > 2) {
- printf("usage: <take> from [to]\r\n");
- return;
- }
- if (argc == 1)
- argv[1] = argv[0];
- cp = expand(argv[1]);
- if ((fd = creat(cp, 0666)) < 0) {
- printf("\r\n%s: cannot create\r\n", argv[1]);
- return;
- }
- sprintf(line, "cat %s;echo \01", argv[0]);
- transfer(line, fd, "\01");
- }
-
- static jmp_buf intbuf;
- /*
- * Bulk transfer routine --
- * used by getfl(), cu_take(), and pipefile()
- */
- transfer(buf, fd, eofchars)
- char *buf, *eofchars;
- {
- register int ct;
- char c, buffer[BUFSIZ];
- register char *p = buffer;
- register int cnt, eof;
- time_t start;
- sigfunc_t (*f)();
-
- pwrite(FD, buf, size(buf));
- quit = 0;
- kill(pid, SIGIOT);
- read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */
-
- /*
- * finish command
- */
- pwrite(FD, "\r", 1);
- do
- read(FD, &c, 1);
- while ((c&0177) != '\n');
- ioctl(0, TIOCSETC, &defchars);
-
- (void) setjmp(intbuf);
- f = signal(SIGINT, intcopy);
- start = time(0);
- for (ct = 0; !quit;) {
- eof = read(FD, &c, 1) <= 0;
- c &= 0177;
- if (quit)
- continue;
- if (eof || any(c, eofchars))
- break;
- if (c == 0)
- continue; /* ignore nulls */
- if (c == '\r')
- continue;
- *p++ = c;
-
- if (c == '\n' && boolean(value(VERBOSE)))
- printf("\r%d", ++ct);
- if ((cnt = (p-buffer)) == number(value(FRAMESIZE))) {
- if (write(fd, buffer, cnt) != cnt) {
- printf("\r\nwrite error\r\n");
- quit = 1;
- }
- p = buffer;
- }
- }
- if (cnt = (p-buffer))
- if (write(fd, buffer, cnt) != cnt)
- printf("\r\nwrite error\r\n");
-
- if (boolean(value(VERBOSE)))
- prtime(" lines transferred in ", time(0)-start);
- ioctl(0, TIOCSETC, &tchars);
- write(fildes[1], (char *)&ccc, 1);
- signal(SIGINT, f);
- close(fd);
- }
-
- /*
- * FTP - remote ==> local process
- * send remote input to local process via pipe
- */
- pipefile()
- {
- int cpid, pdes[2];
- char buf[256];
- int status, p;
- extern int errno;
-
- if (prompt("Local command? ", buf))
- return;
-
- if (pipe(pdes)) {
- printf("can't establish pipe\r\n");
- return;
- }
-
- if ((cpid = fork()) < 0) {
- printf("can't fork!\r\n");
- return;
- } else if (cpid) {
- if (prompt("List command for remote system? ", buf)) {
- close(pdes[0]), close(pdes[1]);
- kill (cpid, SIGKILL);
- } else {
- sigfunc_t (*f)();
-
- close(pdes[0]);
- f = signal(SIGPIPE, intcopy);
- transfer(buf, pdes[1], value(EOFREAD));
- signal(SIGPIPE, f);
- while ((p = wait(&status)) > 0 && p != cpid)
- ;
- }
- } else {
- register int f;
-
- dup2(pdes[0], 0);
- close(pdes[0]);
- for (f = 3; f < 20; f++)
- close(f);
- execute(buf);
- printf("can't execl!\r\n");
- exit(0);
- }
- }
-
- /*
- * Interrupt service routine for FTP
- */
- sigfunc_t
- stopsnd()
- {
-
- stop = 1;
- signal(SIGINT, SIG_IGN);
- }
-
- /*
- * FTP - local ==> remote
- * send local file to remote host
- * terminate transmission with pseudo EOF sequence
- */
- sendfile(cc)
- char cc;
- {
- FILE *fd;
- char *fnamex;
- char *expand();
-
- putchar(cc);
- /*
- * get file name
- */
- if (prompt("Local file name? ", fname))
- return;
-
- /*
- * look up file
- */
- fnamex = expand(fname);
- if ((fd = fopen(fnamex, "r")) == NULL) {
- printf("%s: cannot open\r\n", fname);
- return;
- }
- transmit(fd, value(EOFWRITE), NULL);
- if (!boolean(value(ECHOCHECK)) || boolean(value(LINESYNC))) {
- struct sgttyb buf;
-
- ioctl(FD, TIOCGETP, &buf); /* this does a */
- ioctl(FD, TIOCSETP, &buf); /* wflushtty */
- }
- }
-
- /*
- * Bulk transfer routine to remote host --
- * used by sendfile() and cu_put()
- */
- transmit(fd, eofchars, command)
- FILE *fd;
- char *eofchars, *command;
- {
- char *pc, lastc;
- int c, ccount, lcount;
- time_t start_t, stop_t;
- sigfunc_t (*f)();
-
- kill(pid, SIGIOT); /* put TIPOUT into a wait state */
- stop = 0;
- f = signal(SIGINT, stopsnd);
- ioctl(0, TIOCSETC, &defchars);
- read(repdes[0], (char *)&ccc, 1);
- if (command != NULL) {
- for (pc = command; *pc; pc++)
- send(*pc);
- if (boolean(value(ECHOCHECK)) || boolean(value(LINESYNC)))
- read(FD, (char *)&c, 1); /* trailing \n */
- else {
- struct sgttyb buf;
-
- ioctl(FD, TIOCGETP, &buf); /* this does a */
- ioctl(FD, TIOCSETP, &buf); /* wflushtty */
- sleep(5); /* wait for remote stty to take effect */
- }
- }
- lcount = 0;
- lastc = '\0';
- start_t = time(0);
- while (1) {
- ccount = 0;
- do {
- c = getc(fd);
- if (stop)
- goto out;
- if (c == EOF)
- goto out;
- if (c == 0177 && !boolean(value(RAWFTP)))
- continue;
- lastc = c;
- if (c < 040) {
- if (c == '\n') {
- if (!boolean(value(RAWFTP)))
- c = '\r';
- }
- else if (c == '\t') {
- if (!boolean(value(RAWFTP))) {
- if (boolean(value(TABEXPAND))) {
- send(' ');
- while ((++ccount % 8) != 0)
- send(' ');
- continue;
- }
- }
- } else
- if (!boolean(value(RAWFTP)))
- continue;
- }
- send(c);
- } while (c != '\r' && !boolean(value(RAWFTP)));
- if (boolean(value(VERBOSE)))
- printf("\r%d", ++lcount);
- if (boolean(value(ECHOCHECK)) || boolean(value(LINESYNC))) {
- timedout = 0;
- alarm(value(ETIMEOUT));
- do { /* wait for prompt */
- read(FD, (char *)&c, 1);
- if (timedout || stop) {
- if (timedout)
- printf("\r\ntimed out at eol\r\n");
- alarm(0);
- goto out;
- }
- } while ((c&0177) != character(value(PROMPT)));
- alarm(0);
- }
- }
- out:
- if (lastc != '\n' && !boolean(value(RAWFTP)))
- send('\r');
- for (pc = eofchars; *pc; pc++)
- send(*pc);
- stop_t = time(0);
- fclose(fd);
- signal(SIGINT, f);
- if (boolean(value(VERBOSE)))
- if (boolean(value(RAWFTP)))
- prtime(" chars transferred in ", stop_t-start_t);
- else
- prtime(" lines transferred in ", stop_t-start_t);
- write(fildes[1], (char *)&ccc, 1);
- ioctl(0, TIOCSETC, &tchars);
- }
-
- /*
- * Cu-like put command
- */
- /*ARGUSED*/
- cu_put(cc)
- char cc;
- {
- FILE *fd;
- char line[BUFSIZ];
- int argc;
- char *expand();
- char *copynamex;
-
- if (prompt("[put] ", copyname))
- return;
- if ((argc = args(copyname, argv)) < 1 || argc > 2) {
- printf("usage: <put> from [to]\r\n");
- return;
- }
- if (argc == 1)
- argv[1] = argv[0];
- copynamex = expand(argv[0]);
- if ((fd = fopen(copynamex, "r")) == NULL) {
- printf("%s: cannot open\r\n", copynamex);
- return;
- }
- if (boolean(value(ECHOCHECK)))
- sprintf(line, "cat>%s\r", argv[1]);
- else
- sprintf(line, "stty -echo;cat>%s;stty echo\r", argv[1]);
- transmit(fd, "\04", line);
- }
-
- /*
- * FTP - send single character
- * wait for echo & handle timeout
- */
- send(c)
- char c;
- {
- char cc;
- int retry = 0;
-
- cc = c;
- pwrite(FD, &cc, 1);
- #ifdef notdef
- if (number(value(CDELAY)) > 0 && c != '\r')
- nap(number(value(CDELAY)));
- #endif
- if (!boolean(value(ECHOCHECK))) {
- #ifdef notdef
- if (number(value(LDELAY)) > 0 && c == '\r')
- nap(number(value(LDELAY)));
- #endif
- return;
- }
- tryagain:
- timedout = 0;
- alarm(value(ETIMEOUT));
- read(FD, &cc, 1);
- alarm(0);
- if (timedout) {
- printf("\r\ntimeout error (%s)\r\n", ctrl(c));
- if (retry++ > 3)
- return;
- pwrite(FD, &null, 1); /* poke it */
- goto tryagain;
- }
- }
-
- sigfunc_t
- timeout()
- {
- signal(SIGALRM, timeout);
- timedout = 1;
- }
-
- /*
- * Stolen from consh() -- puts a remote file on the output of a local command.
- * Identical to consh() except for where stdout goes.
- */
- pipeout(c)
- {
- char buf[256];
- int cpid, status, p;
- time_t start;
-
- putchar(c);
- if (prompt("Local command? ", buf))
- return;
- kill(pid, SIGIOT); /* put TIPOUT into a wait state */
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- ioctl(0, TIOCSETC, &defchars);
- read(repdes[0], (char *)&ccc, 1);
- /*
- * Set up file descriptors in the child and
- * let it go...
- */
- if ((cpid = fork()) < 0)
- printf("can't fork!\r\n");
- else if (cpid) {
- start = time(0);
- while ((p = wait(&status)) > 0 && p != cpid)
- ;
- } else {
- register int i;
-
- dup2(FD, 1);
- for (i = 3; i < 20; i++)
- close(i);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- execute(buf);
- printf("can't find `%s'\r\n", buf);
- exit(0);
- }
- if (boolean(value(VERBOSE)))
- prtime("away for ", time(0)-start);
- write(fildes[1], (char *)&ccc, 1);
- ioctl(0, TIOCSETC, &tchars);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- }
-
- #ifdef CONNECT
- /*
- * Fork a program with:
- * 0 <-> local tty in
- * 1 <-> local tty out
- * 2 <-> local tty out
- * 3 <-> remote tty in
- * 4 <-> remote tty out
- */
- consh(c)
- {
- char buf[256];
- int cpid, status, p;
- time_t start;
-
- putchar(c);
- if (prompt("Local command? ", buf))
- return;
- kill(pid, SIGIOT); /* put TIPOUT into a wait state */
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- ioctl(0, TIOCSETC, &defchars);
- read(repdes[0], (char *)&ccc, 1);
- /*
- * Set up file descriptors in the child and
- * let it go...
- */
- if ((cpid = fork()) < 0)
- printf("can't fork!\r\n");
- else if (cpid) {
- start = time(0);
- while ((p = wait(&status)) > 0 && p != cpid)
- ;
- } else {
- register int i;
-
- dup2(FD, 3);
- dup2(3, 4);
- for (i = 5; i < 20; i++)
- close(i);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- execute(buf);
- printf("can't find `%s'\r\n", buf);
- exit(0);
- }
- if (boolean(value(VERBOSE)))
- prtime("away for ", time(0)-start);
- write(fildes[1], (char *)&ccc, 1);
- ioctl(0, TIOCSETC, &tchars);
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- }
- #endif
-
- #ifdef TIPX
- /*
- * filexfer_help
- *
- * Display help for ~X
- * type = 0, general help, 1 = send help, 2 = receive help
- */
- filexfer_help(type)
- int type;
- {
- static char *ghelp[] =
- {
- "for send help, type ~Xs?; for receive help, type ~Xr?",
- "where ~ represents your escape character",
- (char *)0,
- };
- static char *shelp[] =
- {
- "XMODEM (CHK, CRC) and XMODEM-1k/CRC",
- "sx [-ak] filename -a (ASCII) convert NL to CR/LF (default binary)",
- " -k use 1024 blocks instead of 128 (XMODEM-1k)",
- "YMODEM/CRC Batch",
- "sy [-af] filelist -a (ASCII) convert NL to CR/LF (default binary)",
- " -f transfer using full pathanme (default simple)",
- "ZMODEM (CRC-16, CRC-32)",
- "sz [-af+nNyrwo] [-w #] [-L #] [-l #] filelist",
- " -a (ASCII) convert NL to CR/LF (default binary)",
- " not all ZMODEM -f transfer using full pathanme (default simple)",
- " receivers accept -+ Append to existing destination file",
- " all overwrite -n overwrite file if source newer",
- " or append -N overwrite file if source newer or longer",
- " options -y yes, absolutely overwrite existing file",
- " -r Resume/Recover interrupted file transfer",
- " -o use CRC-16 instead of CRC-32",
- " -w # Window is # bytes (>= 256, multiple of 64)",
- " -L # Limit subpacket length to # bytes",
- " -l # Limit frame length to # bytes (l must >= L)",
- (char *)0
- };
- static char *rhelp[] =
- {
- "XMODEM (CHK, CRC) (rcvr tries CRC, then checksum)",
- " rx [-ab] filename",
- "YMODEM/CRC Batch ry [-abu]",
- "ZMODEM (CRC-16, CRC-32) rz [-abu]",
- "Switches: -a force ASCII translation on receive",
- " -b force binary transfer",
- " -u convert uppercase filenames to lower case",
- (char *)0
- };
- char **hh;
-
- switch(type)
- {
- case 0: hh = ghelp; break;
- case 1: hh = shelp; break;
- case 2: hh = rhelp; break;
- }
- while(*hh)
- {
- fputs(*hh++,stdout);
- fputs("\r\n",stdout);
- }
- }
- #endif /* TIPX */
-
- #ifdef TIPX
- /*
- * filexfer
- *
- * Fork a file transfer with:
- * 0 <-> local tty in
- * 1 <-> local tty out
- * 2 <-> local tty out
- * FD <-> remote tty in/out
- */
- filexfer(c)
- {
- char buf[256];
- char xcmd[256+24];
- int cpid, status, p;
- time_t start;
-
- putchar(c);
- if(prompt("\r\nfile transfer command? (? for help) ", buf))
- return;
- if(!strncmp(buf,"sz ",3))
- sprintf(xcmd,"tipsz -Z -. %d ",FD);
- else if(!strncmp(buf,"sy ",3))
- sprintf(xcmd,"tipsz -Y -k -. %d ",FD);
- else if(!strncmp(buf,"sx ",3))
- sprintf(xcmd,"tipsz -X -. %d ",FD);
- else if(!strncmp(buf,"rz",2))
- sprintf(xcmd,"tiprz -Z -. %d ",FD);
- else if(!strncmp(buf,"ry",2))
- sprintf(xcmd,"tiprz -Y -. %d ",FD);
- else if(!strncmp(buf,"rx ",3))
- sprintf(xcmd,"tiprz -X -. %d ",FD);
- else if(!strncmp(buf,"?",1))
- {
- filexfer_help(0);
- return;
- }
- else if(!strncmp(buf,"s?",2))
- {
- filexfer_help(1);
- return;
- }
- else if(!strncmp(buf,"r?",2))
- {
- filexfer_help(2);
- return;
- }
- else
- {
- printf("unrecognized transfer command (use sz, rz, etc.)\r\n");
- return;
- }
- strcat(xcmd,buf + 3);
-
- kill(pid, SIGIOT); /* put TIPOUT into a wait state */
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- unraw();
- read(repdes[0], (char *)&ccc, 1);
- if ((cpid = vfork()) < 0)
- printf("can't fork!\r\n");
- else if (cpid) {
- start = time(0);
- while ((p = wait(&status)) > 0 && p != cpid)
- ;
- } else {
- register int i;
-
- for (i = 3; i < 20; i++)
- {
- if(i != FD)
- close(i);
- }
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- user_uid();
- execl("/bin/sh", "sh", "-c", xcmd, (char *)0);
- printf("can't execute `%s'\n", xcmd);
- perror("execl");
- exit(0);
- }
- prtime("away for ", time(0)-start);
- write(fildes[1], (char *)&ccc, 1);
- raw();
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- }
- #endif
-
- /*
- * Escape to local shell
- */
- shell()
- {
- int shpid, status;
- extern char **environ;
- char *cp;
-
- printf("[sh]\r\n");
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- unraw();
- if (shpid = fork()) {
- while (shpid != wait(&status));
- raw();
- printf("\r\n!\r\n");
- signal(SIGINT, SIG_DFL);
- signal(SIGQUIT, SIG_DFL);
- return;
- } else {
- signal(SIGQUIT, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- if ((cp = rindex(value(SHELL), '/')) == NULL)
- cp = value(SHELL);
- else
- cp++;
- shell_uid();
- execl(value(SHELL), cp, 0);
- printf("\r\ncan't execl!\r\n");
- exit(1);
- }
- }
-
- /*
- * TIPIN portion of scripting
- * initiate the conversation with TIPOUT
- */
- setscript()
- {
- char c;
- /*
- * enable TIPOUT side for dialogue
- */
- kill(pid, SIGEMT);
- if (boolean(value(SCRIPT)))
- write(fildes[1], value(RECORD), size(value(RECORD)));
- write(fildes[1], "\n", 1);
- /*
- * wait for TIPOUT to finish
- */
- read(repdes[0], &c, 1);
- if (c == 'n')
- printf("can't create %s\r\n", value(RECORD));
- }
-
- /*
- * Change current working directory of
- * local portion of tip
- */
- chdirectory()
- {
- char dirname[80];
- register char *cp = dirname;
-
- if (prompt("[cd] ", dirname)) {
- if (stoprompt)
- return;
- cp = value(HOME);
- }
- if (chdir(cp) < 0)
- printf("%s: bad directory\r\n", cp);
- printf("!\r\n");
- }
-
- abort(msg)
- char *msg;
- {
-
- kill(pid, SIGTERM);
- disconnect(msg);
- if (msg != NOSTR)
- printf("\r\n%s", msg);
- printf("\r\n[EOT]\r\n");
- daemon_uid();
- (void)uu_unlock(uucplock);
- unraw();
- exit(0);
- }
-
- finish()
- {
- char *dismsg;
-
- if ((dismsg = value(DISCONNECT)) != NOSTR) {
- write(FD, dismsg, strlen(dismsg));
- sleep(5);
- }
- abort(NOSTR);
- }
-
- sigfunc_t
- intcopy()
- {
-
- raw();
- quit = 1;
- longjmp(intbuf, 1);
- }
-
- execute(s)
- char *s;
- {
- register char *cp;
-
- if ((cp = rindex(value(SHELL), '/')) == NULL)
- cp = value(SHELL);
- else
- cp++;
- user_uid();
- execl(value(SHELL), cp, "-c", s, 0);
- }
-
- args(buf, a)
- char *buf, *a[];
- {
- register char *p = buf, *start;
- register char **parg = a;
- register int n = 0;
-
- do {
- while (*p && (*p == ' ' || *p == '\t'))
- p++;
- start = p;
- if (*p)
- *parg = p;
- while (*p && (*p != ' ' && *p != '\t'))
- p++;
- if (p != start)
- parg++, n++;
- if (*p)
- *p++ = '\0';
- } while (*p);
-
- return(n);
- }
-
- prtime(s, a)
- char *s;
- time_t a;
- {
- register i;
- int nums[3];
-
- for (i = 0; i < 3; i++) {
- nums[i] = (int)(a % quant[i]);
- a /= quant[i];
- }
- printf("%s", s);
- while (--i >= 0)
- if (nums[i] || i == 0 && nums[1] == 0 && nums[2] == 0)
- printf("%d %s%c ", nums[i], sep[i],
- nums[i] == 1 ? '\0' : 's');
- printf("\r\n!\r\n");
- }
-
- variable()
- {
- char buf[256];
-
- if (prompt("[set] ", buf))
- return;
- vlex(buf);
- if (vtable[BEAUTIFY].v_access&CHANGED) {
- vtable[BEAUTIFY].v_access &= ~CHANGED;
- kill(pid, SIGSYS);
- }
- if (vtable[SCRIPT].v_access&CHANGED) {
- vtable[SCRIPT].v_access &= ~CHANGED;
- setscript();
- /*
- * So that "set record=blah script" doesn't
- * cause two transactions to occur.
- */
- if (vtable[RECORD].v_access&CHANGED)
- vtable[RECORD].v_access &= ~CHANGED;
- }
- if (vtable[RECORD].v_access&CHANGED) {
- vtable[RECORD].v_access &= ~CHANGED;
- if (boolean(value(SCRIPT)))
- setscript();
- }
- if (vtable[TAND].v_access&CHANGED) {
- vtable[TAND].v_access &= ~CHANGED;
- if (boolean(value(TAND)))
- tandem("on");
- else
- tandem("off");
- }
- if (vtable[LECHO].v_access&CHANGED) {
- vtable[LECHO].v_access &= ~CHANGED;
- HD = boolean(value(LECHO));
- }
- if (vtable[PARITY].v_access&CHANGED) {
- vtable[PARITY].v_access &= ~CHANGED;
- setparity();
- }
- }
-
- /*
- * Turn tandem mode on or off for remote tty.
- */
- tandem(option)
- char *option;
- {
- struct sgttyb rmtty;
-
- ioctl(FD, TIOCGETP, &rmtty);
- if (strcmp(option,"on") == 0) {
- rmtty.sg_flags |= TANDEM;
- arg.sg_flags |= TANDEM;
- } else {
- rmtty.sg_flags &= ~TANDEM;
- arg.sg_flags &= ~TANDEM;
- }
- ioctl(FD, TIOCSETP, &rmtty);
- ioctl(0, TIOCSETP, &arg);
- }
-
- /*
- * Send a break.
- */
- genbrk()
- {
-
- ioctl(FD, TIOCSBRK, NULL);
- sleep(1);
- ioctl(FD, TIOCCBRK, NULL);
- }
-
- /*
- * Send a ^S.
- */
- #ifdef TIPX
- genctls()
- {
- static char ctls = 0x13;
-
- printf("^S");
- write(FD, &ctls, 1);
- }
- #endif
-
- /*
- * Send a ^Q.
- */
- #ifdef TIPX
- genctlq()
- {
- static char ctlq = 0x11;
-
- printf("^Q");
- write(FD, &ctlq, 1);
- }
- #endif
-
- /*
- * control rawthru mode
- */
- #ifdef TIPX
- rawthru_control(gch)
- char gch;
- {
- extern int rawthru;
- gch &= 0177;
- write(2,&gch,1);
- if(gch == 'R')
- {
- rawthru = 1;
- kill(pid,SIGUSR1);
- }
- else
- {
- rawthru = 0;
- kill(pid,SIGUSR2);
- }
- }
- #endif
-
- /*
- * Suspend tip
- */
- suspend(c)
- char c;
- {
-
- unraw();
- kill(c == CTRL('y') ? getpid() : 0, SIGTSTP);
- raw();
- }
-
- /*
- * expand a file name if it includes shell meta characters
- */
-
- char *
- expand(name)
- char name[];
- {
- static char xname[BUFSIZ];
- char cmdbuf[BUFSIZ];
- register int pid, l;
- register char *cp, *Shell;
- int s, pivec[2];
-
- if (!anyof(name, "~{[*?$`'\"\\"))
- return(name);
- if (pipe(pivec) < 0) {
- perror("pipe");
- /* signal(SIGINT, sigint) */
- return(name);
- }
- sprintf(cmdbuf, "echo %s", name);
- if ((pid = vfork()) == 0) {
- Shell = value(SHELL);
- if (Shell == NOSTR)
- Shell = "/bin/sh";
- close(pivec[0]);
- close(1);
- dup(pivec[1]);
- close(pivec[1]);
- close(2);
- shell_uid();
- execl(Shell, Shell, "-c", cmdbuf, 0);
- _exit(1);
- }
- if (pid == -1) {
- perror("fork");
- close(pivec[0]);
- close(pivec[1]);
- return(NOSTR);
- }
- close(pivec[1]);
- l = read(pivec[0], xname, BUFSIZ);
- close(pivec[0]);
- while (wait(&s) != pid);
- ;
- s &= 0377;
- if (s != 0 && s != SIGPIPE) {
- fprintf(stderr, "\"Echo\" failed\n");
- return(NOSTR);
- }
- if (l < 0) {
- perror("read");
- return(NOSTR);
- }
- if (l == 0) {
- fprintf(stderr, "\"%s\": No match\n", name);
- return(NOSTR);
- }
- if (l == BUFSIZ) {
- fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name);
- return(NOSTR);
- }
- xname[l] = 0;
- for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
- ;
- *++cp = '\0';
- return(xname);
- }
-
- /*
- * Are any of the characters in the two strings the same?
- */
-
- anyof(s1, s2)
- register char *s1, *s2;
- {
- register int c;
-
- while (c = *s1++)
- if (any(c, s2))
- return(1);
- return(0);
- }
-